{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# AI第五周作业——Top20个推荐歌曲"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "import numpy as np\n",
    "import math"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {},
   "outputs": [],
   "source": [
    "import math as mt\n",
    "from scipy.sparse.linalg import * #used for matrix multiplication\n",
    "from scipy.sparse.linalg import svds\n",
    "from scipy.sparse import csc_matrix"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>user</th>\n",
       "      <th>song</th>\n",
       "      <th>listen_count</th>\n",
       "      <th>title</th>\n",
       "      <th>release</th>\n",
       "      <th>artist_name</th>\n",
       "      <th>year</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>d6589314c0a9bcbca4fee0c93b14bc402363afea</td>\n",
       "      <td>SOADQPP12A67020C82</td>\n",
       "      <td>12</td>\n",
       "      <td>You And Me Jesus</td>\n",
       "      <td>Tribute To Jake Hess</td>\n",
       "      <td>Jake Hess</td>\n",
       "      <td>2004</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>d6589314c0a9bcbca4fee0c93b14bc402363afea</td>\n",
       "      <td>SOAFTRR12AF72A8D4D</td>\n",
       "      <td>1</td>\n",
       "      <td>Harder Better Faster Stronger</td>\n",
       "      <td>Discovery</td>\n",
       "      <td>Daft Punk</td>\n",
       "      <td>2007</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>d6589314c0a9bcbca4fee0c93b14bc402363afea</td>\n",
       "      <td>SOANQFY12AB0183239</td>\n",
       "      <td>1</td>\n",
       "      <td>Uprising</td>\n",
       "      <td>Uprising</td>\n",
       "      <td>Muse</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>d6589314c0a9bcbca4fee0c93b14bc402363afea</td>\n",
       "      <td>SOAYATB12A6701FD50</td>\n",
       "      <td>1</td>\n",
       "      <td>Breakfast At Tiffany's</td>\n",
       "      <td>Home</td>\n",
       "      <td>Deep Blue Something</td>\n",
       "      <td>1993</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>d6589314c0a9bcbca4fee0c93b14bc402363afea</td>\n",
       "      <td>SOBOAFP12A8C131F36</td>\n",
       "      <td>7</td>\n",
       "      <td>Lucky (Album Version)</td>\n",
       "      <td>We Sing.  We Dance.  We Steal Things.</td>\n",
       "      <td>Jason Mraz &amp; Colbie Caillat</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                                       user                song  listen_count  \\\n",
       "0  d6589314c0a9bcbca4fee0c93b14bc402363afea  SOADQPP12A67020C82            12   \n",
       "1  d6589314c0a9bcbca4fee0c93b14bc402363afea  SOAFTRR12AF72A8D4D             1   \n",
       "2  d6589314c0a9bcbca4fee0c93b14bc402363afea  SOANQFY12AB0183239             1   \n",
       "3  d6589314c0a9bcbca4fee0c93b14bc402363afea  SOAYATB12A6701FD50             1   \n",
       "4  d6589314c0a9bcbca4fee0c93b14bc402363afea  SOBOAFP12A8C131F36             7   \n",
       "\n",
       "                           title                                release  \\\n",
       "0               You And Me Jesus                   Tribute To Jake Hess   \n",
       "1  Harder Better Faster Stronger                              Discovery   \n",
       "2                       Uprising                               Uprising   \n",
       "3         Breakfast At Tiffany's                                   Home   \n",
       "4          Lucky (Album Version)  We Sing.  We Dance.  We Steal Things.   \n",
       "\n",
       "                   artist_name  year  \n",
       "0                    Jake Hess  2004  \n",
       "1                    Daft Punk  2007  \n",
       "2                         Muse     0  \n",
       "3          Deep Blue Something  1993  \n",
       "4  Jason Mraz & Colbie Caillat     0  "
      ]
     },
     "execution_count": 39,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 读入数据\n",
    "triplet_dataset_sub_song_merged = pd.read_csv('triplet_dataset_sub_song_final.csv') \n",
    "triplet_dataset_sub_song_merged.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>listen_count</th>\n",
       "      <th>year</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>count</th>\n",
       "      <td>1.077456e+07</td>\n",
       "      <td>1.077456e+07</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>mean</th>\n",
       "      <td>4.095210e+00</td>\n",
       "      <td>1.642871e+03</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>std</th>\n",
       "      <td>1.072806e+01</td>\n",
       "      <td>7.669311e+02</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>min</th>\n",
       "      <td>1.000000e+00</td>\n",
       "      <td>0.000000e+00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>25%</th>\n",
       "      <td>1.000000e+00</td>\n",
       "      <td>1.986000e+03</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>50%</th>\n",
       "      <td>2.000000e+00</td>\n",
       "      <td>2.002000e+03</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>75%</th>\n",
       "      <td>4.000000e+00</td>\n",
       "      <td>2.007000e+03</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>max</th>\n",
       "      <td>9.667000e+03</td>\n",
       "      <td>2.010000e+03</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "       listen_count          year\n",
       "count  1.077456e+07  1.077456e+07\n",
       "mean   4.095210e+00  1.642871e+03\n",
       "std    1.072806e+01  7.669311e+02\n",
       "min    1.000000e+00  0.000000e+00\n",
       "25%    1.000000e+00  1.986000e+03\n",
       "50%    2.000000e+00  2.002000e+03\n",
       "75%    4.000000e+00  2.007000e+03\n",
       "max    9.667000e+03  2.010000e+03"
      ]
     },
     "execution_count": 40,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "triplet_dataset_sub_song_merged.describe()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {},
   "outputs": [],
   "source": [
    "song_count_df = pd.read_csv('song_playcount_df.csv')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {},
   "outputs": [],
   "source": [
    "play_count_df = pd.read_csv('user_playcount_df.csv')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {},
   "outputs": [],
   "source": [
    "triplet_dataset_sub_song = pd.read_csv('triplet_dataset_sub_song.csv',encoding = \"ISO-8859-1\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {},
   "outputs": [],
   "source": [
    "import Recommenders as Recommenders\n",
    "from sklearn.model_selection import train_test_split"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "metadata": {},
   "outputs": [],
   "source": [
    "triplet_dataset_sub_song_merged_set = triplet_dataset_sub_song_merged\n",
    "train_data, test_data = train_test_split(triplet_dataset_sub_song_merged_set, test_size = 0.40, random_state=0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>user</th>\n",
       "      <th>song</th>\n",
       "      <th>listen_count</th>\n",
       "      <th>title</th>\n",
       "      <th>release</th>\n",
       "      <th>artist_name</th>\n",
       "      <th>year</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>1901799</th>\n",
       "      <td>28866ea8a809d5d46273cd0989c5515c660ef8c7</td>\n",
       "      <td>SOEYVHS12AB0181D31</td>\n",
       "      <td>1</td>\n",
       "      <td>Monster</td>\n",
       "      <td>The Fame Monster</td>\n",
       "      <td>Lady GaGa</td>\n",
       "      <td>2009</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4815185</th>\n",
       "      <td>c9608a24a2a40e0ec38993a70532e7bb56eff22b</td>\n",
       "      <td>SOKIYKQ12A8AE464FC</td>\n",
       "      <td>2</td>\n",
       "      <td>Fight For Your Life</td>\n",
       "      <td>Made In NYC</td>\n",
       "      <td>The Casualties</td>\n",
       "      <td>2000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>10513026</th>\n",
       "      <td>24f0b09c133a6a0fe42f097734215dceb468d449</td>\n",
       "      <td>SOETFVO12AB018DFF3</td>\n",
       "      <td>1</td>\n",
       "      <td>Free Style (feat. Kevo_ Mussilini &amp; Lyrical 187)</td>\n",
       "      <td>A Bad Azz Mix Tape</td>\n",
       "      <td>Z-RO</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2659073</th>\n",
       "      <td>4da3c59a0af73245cea000fd5efa30384182bfcb</td>\n",
       "      <td>SOAXJOU12A6D4F6685</td>\n",
       "      <td>1</td>\n",
       "      <td>Littlest Things</td>\n",
       "      <td>Alright_ Still</td>\n",
       "      <td>Lily Allen</td>\n",
       "      <td>2006</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5506263</th>\n",
       "      <td>b46c5ed385cad7ecea8af6214f440d19de6eb6c2</td>\n",
       "      <td>SOXBCAY12AB0189EE0</td>\n",
       "      <td>1</td>\n",
       "      <td>La trama y el desenlace</td>\n",
       "      <td>Amar la trama</td>\n",
       "      <td>Jorge Drexler</td>\n",
       "      <td>2010</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                                              user                song  \\\n",
       "1901799   28866ea8a809d5d46273cd0989c5515c660ef8c7  SOEYVHS12AB0181D31   \n",
       "4815185   c9608a24a2a40e0ec38993a70532e7bb56eff22b  SOKIYKQ12A8AE464FC   \n",
       "10513026  24f0b09c133a6a0fe42f097734215dceb468d449  SOETFVO12AB018DFF3   \n",
       "2659073   4da3c59a0af73245cea000fd5efa30384182bfcb  SOAXJOU12A6D4F6685   \n",
       "5506263   b46c5ed385cad7ecea8af6214f440d19de6eb6c2  SOXBCAY12AB0189EE0   \n",
       "\n",
       "          listen_count                                             title  \\\n",
       "1901799              1                                           Monster   \n",
       "4815185              2                               Fight For Your Life   \n",
       "10513026             1  Free Style (feat. Kevo_ Mussilini & Lyrical 187)   \n",
       "2659073              1                                   Littlest Things   \n",
       "5506263              1                           La trama y el desenlace   \n",
       "\n",
       "                     release     artist_name  year  \n",
       "1901799     The Fame Monster       Lady GaGa  2009  \n",
       "4815185          Made In NYC  The Casualties  2000  \n",
       "10513026  A Bad Azz Mix Tape            Z-RO     0  \n",
       "2659073       Alright_ Still      Lily Allen  2006  \n",
       "5506263        Amar la trama   Jorge Drexler  2010  "
      ]
     },
     "execution_count": 46,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "train_data.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "metadata": {},
   "outputs": [],
   "source": [
    "def create_popularity_recommendation(train_data, user_id, item_id):\n",
    "    #Get a count of user_ids for each unique song as recommendation score\n",
    "    train_data_grouped = train_data.groupby([item_id]).agg({user_id: 'count'}).reset_index()\n",
    "    train_data_grouped.rename(columns = {user_id: 'score'},inplace=True)\n",
    "    \n",
    "    #Sort the songs based upon recommendation score\n",
    "    train_data_sort = train_data_grouped.sort_values(['score', item_id], ascending = [0,1])\n",
    "    \n",
    "    #Generate a recommendation rank based upon score\n",
    "    train_data_sort['Rank'] = train_data_sort['score'].rank(ascending=0, method='first')\n",
    "        \n",
    "    #Get the top 10 recommendations\n",
    "    popularity_recommendations = train_data_sort.head(20)\n",
    "    return popularity_recommendations"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "metadata": {},
   "outputs": [],
   "source": [
    "recommendations = create_popularity_recommendation(triplet_dataset_sub_song_merged,'user','title')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>title</th>\n",
       "      <th>score</th>\n",
       "      <th>Rank</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>19580</th>\n",
       "      <td>Sehr kosmisch</td>\n",
       "      <td>18626</td>\n",
       "      <td>1.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5780</th>\n",
       "      <td>Dog Days Are Over (Radio Edit)</td>\n",
       "      <td>17635</td>\n",
       "      <td>2.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>27314</th>\n",
       "      <td>You're The One</td>\n",
       "      <td>16085</td>\n",
       "      <td>3.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>19542</th>\n",
       "      <td>Secrets</td>\n",
       "      <td>15138</td>\n",
       "      <td>4.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>18636</th>\n",
       "      <td>Revelry</td>\n",
       "      <td>14945</td>\n",
       "      <td>5.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>25070</th>\n",
       "      <td>Undo</td>\n",
       "      <td>14687</td>\n",
       "      <td>6.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7530</th>\n",
       "      <td>Fireflies</td>\n",
       "      <td>13085</td>\n",
       "      <td>7.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9640</th>\n",
       "      <td>Hey_ Soul Sister</td>\n",
       "      <td>12993</td>\n",
       "      <td>8.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>25216</th>\n",
       "      <td>Use Somebody</td>\n",
       "      <td>12793</td>\n",
       "      <td>9.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9921</th>\n",
       "      <td>Horn Concerto No. 4 in E flat K495: II. Romanc...</td>\n",
       "      <td>12346</td>\n",
       "      <td>10.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>24291</th>\n",
       "      <td>Tive Sim</td>\n",
       "      <td>11831</td>\n",
       "      <td>11.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3629</th>\n",
       "      <td>Canada</td>\n",
       "      <td>11598</td>\n",
       "      <td>12.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>23468</th>\n",
       "      <td>The Scientist</td>\n",
       "      <td>11529</td>\n",
       "      <td>13.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4194</th>\n",
       "      <td>Clocks</td>\n",
       "      <td>11357</td>\n",
       "      <td>14.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>12135</th>\n",
       "      <td>Just Dance</td>\n",
       "      <td>11058</td>\n",
       "      <td>15.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>26974</th>\n",
       "      <td>Yellow</td>\n",
       "      <td>10919</td>\n",
       "      <td>16.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>16438</th>\n",
       "      <td>OMG</td>\n",
       "      <td>10818</td>\n",
       "      <td>17.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9844</th>\n",
       "      <td>Home</td>\n",
       "      <td>10512</td>\n",
       "      <td>18.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3295</th>\n",
       "      <td>Bulletproof</td>\n",
       "      <td>10383</td>\n",
       "      <td>19.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4760</th>\n",
       "      <td>Creep (Explicit)</td>\n",
       "      <td>10246</td>\n",
       "      <td>20.0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                                                   title  score  Rank\n",
       "19580                                      Sehr kosmisch  18626   1.0\n",
       "5780                      Dog Days Are Over (Radio Edit)  17635   2.0\n",
       "27314                                     You're The One  16085   3.0\n",
       "19542                                            Secrets  15138   4.0\n",
       "18636                                            Revelry  14945   5.0\n",
       "25070                                               Undo  14687   6.0\n",
       "7530                                           Fireflies  13085   7.0\n",
       "9640                                    Hey_ Soul Sister  12993   8.0\n",
       "25216                                       Use Somebody  12793   9.0\n",
       "9921   Horn Concerto No. 4 in E flat K495: II. Romanc...  12346  10.0\n",
       "24291                                           Tive Sim  11831  11.0\n",
       "3629                                              Canada  11598  12.0\n",
       "23468                                      The Scientist  11529  13.0\n",
       "4194                                              Clocks  11357  14.0\n",
       "12135                                         Just Dance  11058  15.0\n",
       "26974                                             Yellow  10919  16.0\n",
       "16438                                                OMG  10818  17.0\n",
       "9844                                                Home  10512  18.0\n",
       "3295                                         Bulletproof  10383  19.0\n",
       "4760                                    Creep (Explicit)  10246  20.0"
      ]
     },
     "execution_count": 49,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "recommendations"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>user</th>\n",
       "      <th>song</th>\n",
       "      <th>listen_count</th>\n",
       "      <th>title</th>\n",
       "      <th>release</th>\n",
       "      <th>artist_name</th>\n",
       "      <th>year</th>\n",
       "      <th>total_listen_count</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>d6589314c0a9bcbca4fee0c93b14bc402363afea</td>\n",
       "      <td>SOADQPP12A67020C82</td>\n",
       "      <td>12</td>\n",
       "      <td>You And Me Jesus</td>\n",
       "      <td>Tribute To Jake Hess</td>\n",
       "      <td>Jake Hess</td>\n",
       "      <td>2004</td>\n",
       "      <td>329</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>d6589314c0a9bcbca4fee0c93b14bc402363afea</td>\n",
       "      <td>SOAFTRR12AF72A8D4D</td>\n",
       "      <td>1</td>\n",
       "      <td>Harder Better Faster Stronger</td>\n",
       "      <td>Discovery</td>\n",
       "      <td>Daft Punk</td>\n",
       "      <td>2007</td>\n",
       "      <td>329</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>d6589314c0a9bcbca4fee0c93b14bc402363afea</td>\n",
       "      <td>SOANQFY12AB0183239</td>\n",
       "      <td>1</td>\n",
       "      <td>Uprising</td>\n",
       "      <td>Uprising</td>\n",
       "      <td>Muse</td>\n",
       "      <td>0</td>\n",
       "      <td>329</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>d6589314c0a9bcbca4fee0c93b14bc402363afea</td>\n",
       "      <td>SOAYATB12A6701FD50</td>\n",
       "      <td>1</td>\n",
       "      <td>Breakfast At Tiffany's</td>\n",
       "      <td>Home</td>\n",
       "      <td>Deep Blue Something</td>\n",
       "      <td>1993</td>\n",
       "      <td>329</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>d6589314c0a9bcbca4fee0c93b14bc402363afea</td>\n",
       "      <td>SOBOAFP12A8C131F36</td>\n",
       "      <td>7</td>\n",
       "      <td>Lucky (Album Version)</td>\n",
       "      <td>We Sing.  We Dance.  We Steal Things.</td>\n",
       "      <td>Jason Mraz &amp; Colbie Caillat</td>\n",
       "      <td>0</td>\n",
       "      <td>329</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                                       user                song  listen_count  \\\n",
       "0  d6589314c0a9bcbca4fee0c93b14bc402363afea  SOADQPP12A67020C82            12   \n",
       "1  d6589314c0a9bcbca4fee0c93b14bc402363afea  SOAFTRR12AF72A8D4D             1   \n",
       "2  d6589314c0a9bcbca4fee0c93b14bc402363afea  SOANQFY12AB0183239             1   \n",
       "3  d6589314c0a9bcbca4fee0c93b14bc402363afea  SOAYATB12A6701FD50             1   \n",
       "4  d6589314c0a9bcbca4fee0c93b14bc402363afea  SOBOAFP12A8C131F36             7   \n",
       "\n",
       "                           title                                release  \\\n",
       "0               You And Me Jesus                   Tribute To Jake Hess   \n",
       "1  Harder Better Faster Stronger                              Discovery   \n",
       "2                       Uprising                               Uprising   \n",
       "3         Breakfast At Tiffany's                                   Home   \n",
       "4          Lucky (Album Version)  We Sing.  We Dance.  We Steal Things.   \n",
       "\n",
       "                   artist_name  year  total_listen_count  \n",
       "0                    Jake Hess  2004                 329  \n",
       "1                    Daft Punk  2007                 329  \n",
       "2                         Muse     0                 329  \n",
       "3          Deep Blue Something  1993                 329  \n",
       "4  Jason Mraz & Colbie Caillat     0                 329  "
      ]
     },
     "execution_count": 54,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "triplet_dataset_sub_song_merged_sum_df = triplet_dataset_sub_song_merged[['user','listen_count']].groupby('user').sum().reset_index()\n",
    "triplet_dataset_sub_song_merged_sum_df.rename(columns={'listen_count':'total_listen_count'},inplace=True)\n",
    "triplet_dataset_sub_song_merged = pd.merge(triplet_dataset_sub_song_merged,triplet_dataset_sub_song_merged_sum_df)\n",
    "triplet_dataset_sub_song_merged.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 55,
   "metadata": {},
   "outputs": [],
   "source": [
    "triplet_dataset_sub_song_merged['fractional_play_count'] = triplet_dataset_sub_song_merged['listen_count']/triplet_dataset_sub_song_merged['total_listen_count']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 56,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>user</th>\n",
       "      <th>song</th>\n",
       "      <th>listen_count</th>\n",
       "      <th>fractional_play_count</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>d6589314c0a9bcbca4fee0c93b14bc402363afea</td>\n",
       "      <td>SOADQPP12A67020C82</td>\n",
       "      <td>12</td>\n",
       "      <td>0.036474</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>d6589314c0a9bcbca4fee0c93b14bc402363afea</td>\n",
       "      <td>SOAFTRR12AF72A8D4D</td>\n",
       "      <td>1</td>\n",
       "      <td>0.003040</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>d6589314c0a9bcbca4fee0c93b14bc402363afea</td>\n",
       "      <td>SOANQFY12AB0183239</td>\n",
       "      <td>1</td>\n",
       "      <td>0.003040</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>d6589314c0a9bcbca4fee0c93b14bc402363afea</td>\n",
       "      <td>SOAYATB12A6701FD50</td>\n",
       "      <td>1</td>\n",
       "      <td>0.003040</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>d6589314c0a9bcbca4fee0c93b14bc402363afea</td>\n",
       "      <td>SOBOAFP12A8C131F36</td>\n",
       "      <td>7</td>\n",
       "      <td>0.021277</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                                       user                song  listen_count  \\\n",
       "0  d6589314c0a9bcbca4fee0c93b14bc402363afea  SOADQPP12A67020C82            12   \n",
       "1  d6589314c0a9bcbca4fee0c93b14bc402363afea  SOAFTRR12AF72A8D4D             1   \n",
       "2  d6589314c0a9bcbca4fee0c93b14bc402363afea  SOANQFY12AB0183239             1   \n",
       "3  d6589314c0a9bcbca4fee0c93b14bc402363afea  SOAYATB12A6701FD50             1   \n",
       "4  d6589314c0a9bcbca4fee0c93b14bc402363afea  SOBOAFP12A8C131F36             7   \n",
       "\n",
       "   fractional_play_count  \n",
       "0               0.036474  \n",
       "1               0.003040  \n",
       "2               0.003040  \n",
       "3               0.003040  \n",
       "4               0.021277  "
      ]
     },
     "execution_count": 56,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "triplet_dataset_sub_song_merged[triplet_dataset_sub_song_merged.user =='d6589314c0a9bcbca4fee0c93b14bc402363afea'][['user','song','listen_count','fractional_play_count']].head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 57,
   "metadata": {},
   "outputs": [],
   "source": [
    "from scipy.sparse import coo_matrix\n",
    "\n",
    "small_set = triplet_dataset_sub_song_merged\n",
    "user_codes = small_set.user.drop_duplicates().reset_index()\n",
    "song_codes = small_set.song.drop_duplicates().reset_index()\n",
    "user_codes.rename(columns={'index':'user_index'}, inplace=True)\n",
    "song_codes.rename(columns={'index':'song_index'}, inplace=True)\n",
    "song_codes['so_index_value'] = list(song_codes.index)\n",
    "user_codes['us_index_value'] = list(user_codes.index)\n",
    "small_set = pd.merge(small_set,song_codes,how='left')\n",
    "small_set = pd.merge(small_set,user_codes,how='left')\n",
    "mat_candidate = small_set[['us_index_value','so_index_value','fractional_play_count']]\n",
    "data_array = mat_candidate.fractional_play_count.values\n",
    "row_array = mat_candidate.us_index_value.values\n",
    "col_array = mat_candidate.so_index_value.values\n",
    "\n",
    "data_sparse = coo_matrix((data_array, (row_array, col_array)),dtype=float)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 58,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<99612x4001 sparse matrix of type '<class 'numpy.float64'>'\n",
       "\twith 3712888 stored elements in COOrdinate format>"
      ]
     },
     "execution_count": 58,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data_sparse"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 59,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>user_index</th>\n",
       "      <th>user</th>\n",
       "      <th>us_index_value</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>27413</th>\n",
       "      <td>1023016</td>\n",
       "      <td>2a2f776cbac6df64d6cb505e7e834e01684673b6</td>\n",
       "      <td>27413</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "       user_index                                      user  us_index_value\n",
       "27413     1023016  2a2f776cbac6df64d6cb505e7e834e01684673b6           27413"
      ]
     },
     "execution_count": 59,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "user_codes[user_codes.user =='2a2f776cbac6df64d6cb505e7e834e01684673b6']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 60,
   "metadata": {},
   "outputs": [],
   "source": [
    "import math as mt\n",
    "from scipy.sparse.linalg import * #used for matrix multiplication\n",
    "from scipy.sparse.linalg import svds\n",
    "from scipy.sparse import csc_matrix"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 61,
   "metadata": {},
   "outputs": [],
   "source": [
    "def compute_svd(urm, K):\n",
    "    U, s, Vt = svds(urm, K)\n",
    "\n",
    "    dim = (len(s), len(s))\n",
    "    S = np.zeros(dim, dtype=np.float32)\n",
    "    for i in range(0, len(s)):\n",
    "        S[i,i] = mt.sqrt(s[i])\n",
    "\n",
    "    U = csc_matrix(U, dtype=np.float32)\n",
    "    S = csc_matrix(S, dtype=np.float32)\n",
    "    Vt = csc_matrix(Vt, dtype=np.float32)\n",
    "    \n",
    "    return U, S, Vt\n",
    "\n",
    "def compute_estimated_matrix(urm, U, S, Vt, uTest, K, test):\n",
    "    rightTerm = S*Vt \n",
    "    max_recommendation = 250\n",
    "    estimatedRatings = np.zeros(shape=(MAX_UID, MAX_PID), dtype=np.float16)\n",
    "    recomendRatings = np.zeros(shape=(MAX_UID,max_recommendation ), dtype=np.float16)\n",
    "    for userTest in uTest:\n",
    "        prod = U[userTest, :]*rightTerm\n",
    "        estimatedRatings[userTest, :] = prod.todense()\n",
    "        recomendRatings[userTest, :] = (-estimatedRatings[userTest, :]).argsort()[:max_recommendation]\n",
    "    return recomendRatings"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 62,
   "metadata": {},
   "outputs": [],
   "source": [
    "K=50\n",
    "urm = data_sparse\n",
    "MAX_PID = urm.shape[1]\n",
    "MAX_UID = urm.shape[0]\n",
    "\n",
    "U, S, Vt = compute_svd(urm, K)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 63,
   "metadata": {},
   "outputs": [],
   "source": [
    "uTest = [4,5,6,7,8,873,23]\n",
    "\n",
    "uTest_recommended_items = compute_estimated_matrix(urm, U, S, Vt, uTest, K, True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 64,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Recommendation for user with user id 4\n",
      "The number 1 recommended song is Rayando el sol BY ManÃ¡\n",
      "The number 2 recommended song is Fireflies BY Charttraxx Karaoke\n",
      "The number 3 recommended song is Hey_ Soul Sister BY Train\n",
      "The number 4 recommended song is Epilogue BY Asia 2001\n",
      "The number 5 recommended song is Crumpshit BY Philippe Rochard\n",
      "The number 6 recommended song is I Feel Home (Album Version) BY O.A.R.\n",
      "The number 7 recommended song is Picture BY Sheryl Crow\n",
      "The number 8 recommended song is Lucky (Album Version) BY Jason Mraz & Colbie Caillat\n",
      "The number 9 recommended song is Kryptonite BY 3 Doors Down\n",
      "The number 10 recommended song is Timewarp BY Sub Focus\n",
      "Recommendation for user with user id 5\n",
      "The number 1 recommended song is Tive Sim BY Cartola\n",
      "The number 2 recommended song is Epilogue BY Asia 2001\n",
      "The number 3 recommended song is Shoot Me Again BY Metallica\n",
      "The number 4 recommended song is Dog Days Are Over (Radio Edit) BY Florence + The Machine\n",
      "The number 5 recommended song is Sehr kosmisch BY Harmonia\n",
      "The number 6 recommended song is Ain't Misbehavin BY Sam Cooke\n",
      "The number 7 recommended song is Wild World BY Cat Stevens\n",
      "The number 8 recommended song is Revelry BY Kings Of Leon\n",
      "The number 9 recommended song is Undo BY BjÃ¶rk\n",
      "The number 10 recommended song is Una Confusion BY LU\n",
      "Recommendation for user with user id 6\n",
      "The number 1 recommended song is Crumpshit BY Philippe Rochard\n",
      "The number 2 recommended song is I Feel Home (Album Version) BY O.A.R.\n",
      "The number 3 recommended song is Hey_ Soul Sister BY Train\n",
      "The number 4 recommended song is Marry Me BY Train\n",
      "The number 5 recommended song is Lucky (Album Version) BY Jason Mraz & Colbie Caillat\n",
      "The number 6 recommended song is Bring Me To Life BY Evanescence\n",
      "The number 7 recommended song is Kryptonite BY 3 Doors Down\n",
      "The number 8 recommended song is Timewarp BY Sub Focus\n",
      "The number 9 recommended song is Canada BY Five Iron Frenzy\n",
      "The number 10 recommended song is Picture BY Sheryl Crow\n",
      "Recommendation for user with user id 7\n",
      "The number 1 recommended song is Una Confusion BY LU\n",
      "The number 2 recommended song is Home BY Edward Sharpe & The Magnetic Zeros\n",
      "The number 3 recommended song is Creep (Explicit) BY Radiohead\n",
      "The number 4 recommended song is Wild World BY Cat Stevens\n",
      "The number 5 recommended song is The Funeral (Album Version) BY Band Of Horses\n",
      "The number 6 recommended song is Dead Souls BY Nine Inch Nails\n",
      "The number 7 recommended song is Tighten Up BY The Black Keys\n",
      "The number 8 recommended song is Behind The Sea [Live In Chicago] BY Panic At The Disco\n",
      "The number 9 recommended song is Oceanside BY Angels Of Light & Akron/Family\n",
      "The number 10 recommended song is What You Know BY Two Door Cinema Club\n",
      "Recommendation for user with user id 8\n",
      "The number 1 recommended song is Undo BY BjÃ¶rk\n",
      "The number 2 recommended song is Better To Reign In Hell BY Cradle Of Filth\n",
      "The number 3 recommended song is Canada BY Five Iron Frenzy\n",
      "The number 4 recommended song is Unite (2009 Digital Remaster) BY Beastie Boys\n",
      "The number 5 recommended song is Behind The Sea [Live In Chicago] BY Panic At The Disco\n",
      "The number 6 recommended song is Revelry BY Kings Of Leon\n",
      "The number 7 recommended song is Almaz BY Randy Crawford\n",
      "The number 8 recommended song is 16 Candles BY The Crests\n",
      "The number 9 recommended song is Catch You Baby (Steve Pitron & Max Sanna Radio Edit) BY Lonnie Gordon\n",
      "The number 10 recommended song is Where You From? BY RinÃ´Ã§Ã©rÃ´se / Mark Gardener\n",
      "Recommendation for user with user id 873\n",
      "The number 1 recommended song is Secrets BY OneRepublic\n",
      "The number 2 recommended song is All The Right Moves BY OneRepublic\n",
      "The number 3 recommended song is Canada BY Five Iron Frenzy\n",
      "The number 4 recommended song is Apologize BY OneRepublic\n",
      "The number 5 recommended song is Breakeven BY The Script\n",
      "The number 6 recommended song is Use Somebody BY Kings Of Leon\n",
      "The number 7 recommended song is You'd Be So Nice To Come Home To BY Julie London\n",
      "The number 8 recommended song is Heartbreak Warfare BY John Mayer\n",
      "The number 9 recommended song is Everybody Loves Me BY OneRepublic\n",
      "The number 10 recommended song is The Only Exception (Album Version) BY Paramore\n",
      "Recommendation for user with user id 23\n",
      "The number 1 recommended song is Who Is Watching BY Armin van Buuren feat. Nadia Ali\n",
      "The number 2 recommended song is The Memory Remains BY Metallica / Marianne Faithfull\n",
      "The number 3 recommended song is Wrong Way To Hollywood (Live) BY Wall Of Voodoo\n",
      "The number 4 recommended song is One BY Metallica\n",
      "The number 5 recommended song is Epilogue BY Asia 2001\n",
      "The number 6 recommended song is Brothers And Sisters BY Ziggy Marley And The Melody Makers\n",
      "The number 7 recommended song is So Cold In Ireland BY The Cranberries\n",
      "The number 8 recommended song is Enter Sandman BY Metallica\n",
      "The number 9 recommended song is Paradise City BY Guns N' Roses\n",
      "The number 10 recommended song is Don't Cry (Original) BY Guns N' Roses\n"
     ]
    }
   ],
   "source": [
    "for user in uTest:\n",
    "    print(\"Recommendation for user with user id {}\". format(user))\n",
    "    rank_value = 1\n",
    "    for i in uTest_recommended_items[user,0:10]:\n",
    "        song_details = small_set[small_set.so_index_value == i].drop_duplicates('so_index_value')[['title','artist_name']]\n",
    "        print(\"The number {} recommended song is {} BY {}\".format(rank_value, list(song_details['title'])[0],list(song_details['artist_name'])[0]))\n",
    "        rank_value+=1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
